#include <QApplication>

#include "system/systeminfo.h"
#include "enc_dec/base64.h"
#include "enc_dec/md5.h"
#include "net/HttpDownload.h"
#include "log/log.h"
#include "string/string_ext.h"

#include "container/RingQueue.h"
#include "container/HashList.h"

#include "string/Md5Util.h"
#include "system/app_config_setting.h"
#include "ui_component/filedialog.h"
#include "enc_dec/wg_ten_to_8.h"
#include "system/SingleApp.h"
#include "container/LRUCache.h"

#include <QThread>
#include <QDateTime>
#include <QTimer>

void LRUCache_test()
{
    LRUCache<std::string,std::string> m_cache(3);

    m_cache.insert("xm","xiaoming"); // 先被挤掉
    m_cache.insert("xl","xiaoli");
    m_cache.insert("xw","xiaowang");

    qDebug() << m_cache.dataCount() << m_cache.count();

    qDebug() << m_cache.value("xl").c_str();

    m_cache.insert("xh","xiaohua");

    qDebug() << "isNull?" << m_cache.take("xm").c_str();//添加xh，此时xm被顶掉，该值为空

    m_cache["xl"] = "XL"; // 更改缓存值

    qDebug() << m_cache.contains("xl");
    qDebug() << m_cache.contains("xx");
}

bool single_app_test()
{
    /* 注意生命周期（这里只是演示），对于多进程APP，需要考虑进程的创建先后顺序 */
    SingleApp myapp("myapp");
    if (myapp.hasPreviousInstance()) {
        return EXIT_SUCCESS;
    }

    if (!myapp.start()) {
        qDebug() << myapp.getLastErrorString();
        return EXIT_FAILURE;
    }


    QObject::connect(&myapp, &SingleApp::newInstanceCreated, []() {

        /* TODO主界面唤醒代码 */
    });
}

void base_h()
{
    //md5散列
    qDebug() << getHashMd5(QString("/Users/monster/TEST.pptx"));
    qDebug() << getHashMd5(QByteArray("123456"));

}

void app_config_setting_h()
{
    AppConfigSetting::instance().set("name","xiaoming");
    AppConfigSetting::instance().set("age",12);
    qDebug() << AppConfigSetting::instance().get("age");
}

void base64_h()
{
    IBase64 src;
    char data[] = "abcd";
    src.data = data;
    src.size = 4;//由于支持\0问题，strlen计算有时候是不可用的
    IBase64 *dst = base64_encode(src);
    IBase64 *dstToSrc = base64_decode(*dst);

    qDebug() << dst->data;
    qDebug() << dstToSrc->data;
    base64_free(dst);
    base64_free(dstToSrc);
}

void md5_h()
{
    MD5_CTX md5;
    unsigned char encrypt[16]="123456";//需要散列的内容
    unsigned char decrypt[16];//md5(123456,32) = e10adc3949ba59abbe56e057f20f883e
    MD5Init(&md5);
    MD5Update(&md5,encrypt,strlen((char *)encrypt));
    MD5Final(&md5,decrypt);
    QString decStr;
    for (int i=0;i<16;i++) {
        char hex[3] = {0};
        sprintf(hex,"%02x",decrypt[i]);
        decStr += hex;
    }
    qDebug() << decStr;
}

void systeminfo_h()
{
    QTimer * timer = new QTimer;
    QObject::connect(timer,&QTimer::timeout,[](){
        qDebug() << "ram:" << SystemInfo::getRamSizeOfSelf();
    });
    qDebug() << "os" << SystemInfo::getOSInfo();
    qDebug() << "cpu" << SystemInfo::getCPUInfo();
    qDebug() << "ip:" << SystemInfo::getIPAddress();
    qDebug() << "mac:" << SystemInfo::getMACAdress();
    qDebug() << "avaliable ram" << SystemInfo::getAvaliableRamSize();
    qDebug() << "peak size" << SystemInfo::getPeakRamSizeOfSelf();
    qDebug() << "phisycal" << SystemInfo::getRamSizeOfSelf();
    qDebug() << "wifi is Connected" << SystemInfo::isWlanConnected();
    qDebug() << "wifi list" << SystemInfo::getWlanNames();
    timer->start(5000);
    qDebug() << SystemInfo::isVirtualSystem();
    SystemInfo::storageInfo();
}

void log_h()
{
    TKGLog::Instance()->set_file_name("testlog");
    TKGwrite_log_info("info %s","generate");
    TKGwrite_log_error("error %d",1024);
    TKGwrite_log_warning("warning: %f",123.4);
}

void httpdownload_h()
{
    static QThread thread;    //这里为了测试方便使用了static
    static HttpDownload http(0);
    http.setParam("https://dldir1.qq.com/qqfile/QQforMac/QQ_V6.4.0.dmg","qq.dmg","");
    //    http.setParam("https://dldir1.qq.com/qqfile/QQforMac/QQ_V6.4.0.dmg","qq.dmg","/Users/test/");
    http.moveToThread(&thread);
    QObject::connect(&http,&HttpDownload::finished,&thread,&QThread::quit);
    QObject::connect(&http,&HttpDownload::finished,[](int size){
        qDebug() << "download completed!" << size;
    });
    QObject::connect(&thread,&QThread::started,&http,&HttpDownload::launch);
    thread.start();

}

void string_ext_h()
{
    QList<QString> list {"a","b","c","d"};
    QMap<QString,QString> map{{"key","value"},{"key1","value1"}};
    qDebug() << QString("base") << "哈哈" << list << map;
    QString test2;
    test2 = QString("") << 1 << 2;
    qDebug() << test2;
}

void filedialog_h()
{
    static FileDialog dialog(0, QDir::homePath(), u8"选择文件", "Doc Files(*.doc *.docx *.ppt *.pptx *.pdf)");
    QObject::connect(&dialog,&FileDialog::emitFiles,[](const QStringList &list){
        qDebug() << "选择文件" << list;
    });
    dialog.show();
}

void RingQueue_h()
{
    RingQueue ring(1024);

    char buf[10] = {'a','b','c','d','e','f','g'};
    ring.writeData((const unsigned char*)buf,8);

    char readBuf[4] = {0};

    qDebug() << ring.readData((unsigned char*)readBuf,10); // invalid return 0

    if (ring.readData((unsigned char*)readBuf,3)) {
        qDebug() << readBuf[0] << readBuf[1] << readBuf[2];
    } // ok

}

void HashList_h()
{
    HashList<QString,int> hl;
    hl.append("12",3);
    hl.append("123",4);
    //    hl.append("242",20);
    hl.append("2w4",140);
    //    hl.append("2a4",320);
    hl.append("2d24",29830);
    hl.push_front("haha",99999);
    hl.append("122r4",201672);
    hl.append("20op4",212);

    qDebug() << hl.at(5) << hl.at(1);
    hl.removeAt(3);
    qDebug() << hl.count();
    hl.removeAt(4);
    qDebug() << hl.at(3) << hl.at(1);
    //    qDebug() << hl.

}

void wgTenTo8_h()
{
    qDebug() << wgTenTo8("1234567891");//ok
    qDebug() << wgTenTo8("a234567891");//error
    qDebug() << wgTenTo8("1234567891a");//error
    qDebug() << wgTenTo8("123456781");//error
}

int main(int argc, char *argv[])
{
    QApplication a(argc,argv);
    //    md5_h();
    systeminfo_h();
    LRUCache_test();
    //    base64_h();
    //    httpdownload_h();
    //    log_h();
    //    string_ext_h();
    //    base_h();
    //    app_config_setting_h();
    //     filedialog_h();
    //    systeminfo_h();

    //    RingQueue_h();
    //    HashList_h();
    //    RingQueue_h();
    //    HashList_h();
    //    wgTenTo8_h();
    return a.exec();
}
